package com.tdk.wifidirectserver.ui.main

import android.content.Context
import android.net.nsd.NsdManager
import android.net.nsd.NsdServiceInfo
import android.os.Environment
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.tdk.wifidirectserver.MyApplication
import com.tdk.wifidirectserver.bean.MessageBean
import com.tdk.wifidirectserver.nsd.NsdClient
import com.tdk.wifidirectserver.socket.client.Client
import com.tdk.wifidirectserver.socket.client.IClientListener
import com.tdk.wifidirectserver.socket.server.IServerListener
import com.tdk.wifidirectserver.socket.server.Server
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileOutputStream
import java.nio.ByteBuffer

class ConnectedClientViewModel : ViewModel() {
    private val TAG: String = "ConnectedClientViewModel"
    private var client: Client? = null
    var messageList: MutableList<MessageBean> = mutableListOf()
    var messageListUpdateLiveData: MutableLiveData<Int> = MutableLiveData()

    var socketConnectStatus = MutableLiveData<Boolean>(false)

    var nsdClient: NsdClient? = null
//    var discoveryListener: NsdManager.DiscoveryListener? = null

    var nsdServiceInfoLiveData: MutableLiveData<NsdServiceInfo> = MutableLiveData()

    var serviceInfoList: MutableLiveData<MutableList<NsdServiceInfo>> = MutableLiveData(mutableListOf())

    var isTransfer = false

    @Volatile
    var discoveryNSDStatus = 0 // 0 未开始 【关闭发现成功】   1 正在打开发现 2 打开发现成功 3 正在关闭发现

    private val lock = Any()

    fun startClient(ip: String, port: Int) {
        client = Client(null, ip, port)
        client!!.setIClientListener(object : IClientListener {


            override fun onConnectSuccess() {
                Log.d(TAG, "onConnectSuccess")
                socketConnectStatus.postValue(true)
            }

            override fun onConnectFailure() {
                Log.d(TAG, "onConnectFailure")
                socketConnectStatus.postValue(false)
                client = null

            }

            override fun onDisconnected() {
                Log.d(TAG, "onDisconnected")
                socketConnectStatus.postValue(false)
                client = null
            }

            override fun parseData(bytes: ByteArray?) {
                Log.d(TAG, "parseData ${String(bytes!!)}")
                if (!isTransfer) {
                    messageList.add(MessageBean(String(bytes), MessageBean.MESSAGE_RECEIVE))
                    messageListUpdateLiveData.postValue(messageList.size)
                } else {
                    //每次写入10240字节到文件中
                    val file = File(Environment.getExternalStorageDirectory().absolutePath + "/Download/" + "test.txt")
                    file.createNewFile()
                    val fileOutputStream = FileOutputStream(file, true)
                    //读取byte数组0-8位，转换成long，得到文件总长度
                    val totalLength = bytes.copyOfRange(0, 7)
                    //读取byte数组数据


                    //读取byte数组第8位开始的数据
                    val data = bytes.copyOfRange(8, bytes.size)
                    fileOutputStream.write(data)


                    fileOutputStream.write(bytes)
                    fileOutputStream.flush()


                }


            }

            override fun serverClose() {
                Log.d(TAG, "serverClose")
                socketConnectStatus.postValue(false)
            }


        })
        client!!.connect()
    }

    fun closeClient() {
        client?.disconnect()
    }

    fun sengMsg(msg: String) {
        messageList.add(MessageBean(msg, MessageBean.MESSAGE_SEND))
        messageListUpdateLiveData.postValue(messageList.size)
        client?.sendData(msg)
    }

    var discoveryListener: NsdManager.DiscoveryListener? = null
    //添加同步代码块

    @Synchronized
    fun startDiscoveryNSD() {
        Log.d(TAG, "startDiscoveryNSD111111 discoveryNSDStatus = $discoveryNSDStatus")
        if (discoveryNSDStatus == 0) {
            discoveryNSDStatus = 1
            nsdClient = NsdClient()

            nsdClient!!.mNsdServiceLostCallback = {
                Log.d(TAG, "mNsdServiceLostCallback")
                val tempList = serviceInfoList.value ?: mutableListOf()
                if (tempList.contains(it)) {
                    tempList.remove(it)
                    serviceInfoList.postValue(tempList)
                }

            }

            nsdClient!!.mNsdServiceInfoFindCallback = {
                Log.d(TAG, "mNsdServiceFoundCallback $it")

                val temp = serviceInfoList.value ?: mutableListOf()
                val isExist = temp.find { nsdServiceInfo ->
                    nsdServiceInfo.serviceName == it.serviceName && nsdServiceInfo.serviceType == it.serviceType
                }
                if (isExist == null) {
                    temp.add(it)
                } else {
                    temp.remove(isExist)
                    temp.add(it)
                }
                nsdServiceInfoLiveData.postValue(it)
                serviceInfoList.postValue(temp)
            }
             discoveryListener = object : NsdManager.DiscoveryListener {
                override fun onStartDiscoveryFailed(serviceType: String?, errorCode: Int) {
                    Log.d(TAG, "onStartDiscoveryFailed $errorCode")
                    discoveryNSDStatus = 0
                }

                override fun onStopDiscoveryFailed(serviceType: String?, errorCode: Int) {
                    Log.d(TAG, "onStopDiscoveryFailed $errorCode")
                }

                override fun onDiscoveryStarted(serviceType: String?) {
                    Log.d(TAG, "onDiscoveryStarted  serviceType $serviceType")
                    discoveryNSDStatus = 2
                }

                override fun onDiscoveryStopped(serviceType: String?) {
                    Log.d(TAG, "onDiscoveryStopped  serviceType $serviceType")
                    serviceInfoList.postValue(mutableListOf())
                    discoveryListener = null
                    discoveryNSDStatus = 0
//                    GlobalScope.launch(Dispatchers.IO) {
//                        delay(5000)
//
//                    }

                }

                override fun onServiceFound(serviceInfo: NsdServiceInfo?) {
                    Log.d(TAG, "onServiceFound  serviceInfo $serviceInfo")
                    nsdClient?.solve(MyApplication.instance as Context, serviceInfo)
                }

                override fun onServiceLost(serviceInfo: NsdServiceInfo?) {
                    Log.d(TAG, "onServiceLost  serviceInfo $serviceInfo")
                }

            }
            nsdClient?.discoverService(MyApplication.instance as Context, discoveryListener!!, "_wifi._tcp.")

        } else {
            Log.d(TAG, "startDiscoveryNSD discoveryNSDStatus $discoveryNSDStatus")
        }


    }

    @Synchronized
    fun stopDiscoveryNSD() {
        Log.d(TAG, "stopDiscoveryNSD  discoveryNSDStatus $discoveryNSDStatus")
        if (discoveryNSDStatus == 2) {
            discoveryNSDStatus = 3
            if (discoveryListener != null && nsdClient != null) {
                nsdClient?.stopDiscoverListener(MyApplication.instance as Context, discoveryListener!!)
            } else {
                Log.d(TAG, "stopDiscoveryNSD  discoveryListener :$discoveryListener is null or nsdClient $nsdClient is null")
            }
        } else {
            Log.d(TAG, "stopDiscoveryNSD  discoveryNSDStatus $discoveryNSDStatus is not 2")
        }

    }


}